package com.maxdu.labs.stt.fragments;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.stt.R;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.model.GraphUser;
import com.maxdu.labs.stt.constants.Constants;
import com.maxdu.labs.stt.models.TPlan;
import com.maxdu.labs.stt.models.Training;
import com.maxdu.labs.stt.models.TrainingType;
import com.maxdu.labs.stt.models.db.TPlanDBHelper;
import com.maxdu.labs.stt.models.db.UserVSTPlanDBHelper;
import com.parse.FindCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;

public class TrainingsFragment extends Fragment {
	
	private final int TRAININGS_TO_SHOW = 50;
	
	private ProgressBar loading;
	private TextView somethingWentWrongTV;
	private TextView noTrainingTV;
	private ListView trainingsLV;
	
	private List<Training> myLastTrainings;
	private List<String> tplanIds;
	private List<TPlan> tplans;
	private TrainingAdapter adapter;
	
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
          Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.frag_my_last_trainings, container, false);
      
    //((MainTestMenuActivity)getActivity()).setActionBarTitle(getString(R.string.my_trainings));
    
      loading = (ProgressBar)view.findViewById(R.id.loading);
      somethingWentWrongTV = (TextView)view.findViewById(R.id.tv_something_went_wrong);
      noTrainingTV = (TextView)view.findViewById(R.id.tv_no_training);
      trainingsLV = (ListView)view.findViewById(R.id.lv_trainings);
      
      myLastTrainings = new ArrayList<Training>();
      
      adapter = new TrainingAdapter(getActivity(), R.layout.row_training_request, myLastTrainings);
      trainingsLV.setAdapter(adapter);
      
	   Session session = Session.getActiveSession();
	    if (session != null && session.isOpened()) {
	    	
	        // Get the user's data
	        makeMeRequest(session);
	    }
      
      return view;
   }
   
   private void makeMeRequest(final Session session) {
	    Request request = Request.newMeRequest(session, 
	            new Request.GraphUserCallback() {

	        @Override
	        public void onCompleted(GraphUser user, Response response) {
	            // If the response is successful
	            if (session == Session.getActiveSession()) {
	                if (user != null) {
	                    String userId = user.getId();
	                    getMyLastTrainings(userId,TRAININGS_TO_SHOW);
	                    
	                }
	            }
	            if (response.getError() != null) {
	                // Handle error
	            }
	        }
	    });
	    request.executeAsync();
	} 
   
   private void getMyLastTrainings(final String userId, int n){
	   
    	ParseQuery<ParseObject> query = ParseQuery.getQuery(Training.PARSE_DB_TABLENAME);
		query.whereEqualTo(Training.PARSE_DB_FIELD_USERID, userId);
		query.orderByDescending(Training.PARSE_DB_FIELD_DATE);
		query.setLimit(n);
		
		query.findInBackground(new FindCallback<ParseObject>() {
		    public void done(List<ParseObject> myLastTrainingsPO, ParseException e) {
		        if (e == null) {
		        	if (myLastTrainingsPO != null && myLastTrainingsPO.size()> 0){
		        		
		        		Log.d(Constants.LOG_TAG,"we found [" + myLastTrainingsPO.size() + "] trainings for this user [" + userId +"]");
		        		for (ParseObject training : myLastTrainingsPO){
		        			myLastTrainings.add(new Training(training.getString(Training.PARSE_DB_FIELD_TPLANID),
		        													training.getString(Training.PARSE_DB_FIELD_USERID),
		        													training.getLong(Training.PARSE_DB_FIELD_DATE),
		        													training.getInt(Training.PARSE_DB_FIELD_TRAINING_TYPE)));
		        		}
		        		getTPlanIdsOfTheseTrainings(myLastTrainings);
		        		
		        		GetTPlansTask task = new GetTPlansTask();
		        		task.execute();
		        		
		        	}else if(myLastTrainingsPO == null){
		        		loading.setVisibility(View.GONE);
			        	somethingWentWrongTV.setVisibility(View.VISIBLE);
		        		Log.w(Constants.LOG_TAG,"We couldn't find the Trainings for this User [" + userId + "]. Training list is NULL");
		        	}else{
		        		loading.setVisibility(View.GONE);
		        		noTrainingTV.setVisibility(View.VISIBLE);
		        		Log.d(Constants.LOG_TAG,"We couldn't find the Trainings for this User [" + userId + "]. Training list is EMPTY");
		        	}
		        } else {
		            Log.d(Constants.LOG_TAG, "Error: " + e.getMessage());
		        }
		    }
		});
   }
   
   private void getTPlanIdsOfTheseTrainings(List<Training> trainings){
	   
	   tplanIds = new ArrayList<String>();
	   
	   tplanIds.add(trainings.get(0).getTPlanId());
	   
	   for(Training training : trainings){
		   if (!tplanIds.contains(training.getTPlanId())){
			   tplanIds.add(training.getTPlanId());
		   }
	   }
   }
   
   private class TrainingAdapter extends ArrayAdapter<Training>{

		List<Training> trainings;
		
		public TrainingAdapter(Context context, int resource,
				List<Training> objects) {
			super(context, resource, objects);
			
			trainings = objects;
		}
		
		@Override
	    public View getView(final int position, View convertView, ViewGroup parent) {
			
	        View view = convertView;
	        if (view == null) {
	        	LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
	        		      (Context.LAYOUT_INFLATER_SERVICE);
	            view = inflater.inflate(R.layout.row_my_trainings, parent,false);
	        }
	
	        final Training training = trainings.get(position);
	        
	        ImageView trainingTypeIcon = (ImageView) view.findViewById(R.id.image_type);
	        TextView tplanNameTV = (TextView) view.findViewById(R.id.tv_tplan_name);
	        TextView dateTV = (TextView) view.findViewById(R.id.tv_date);
	        
	        Date date = new Date(training.getDate());
	        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
	        dateTV.setText(format.format(date));
	        if (tplans.indexOf(training.getTPlanId()) > -1){
	        	tplanNameTV.setText(tplans.get(tplans.indexOf(training.getTPlanId())).getName());
	        }
	        for(TPlan tplan : tplans){
	        	if (tplan.getId().equals(training.getTPlanId())){
	        		tplanNameTV.setText(tplan.getName());
	        	}
	        }
	        
	        switch (training.getType()) {
				case TrainingType.TYPE_CLIMBING:
					trainingTypeIcon.setImageResource(R.drawable.climbing_icon);
					break;
	
				default:
					trainingTypeIcon.setImageResource(R.drawable.running_icon);
					break;
			}
	        
	        return view;
	    }
	}
   
   
   private class GetTPlansTask extends AsyncTask<Void, Void, List<TPlan>> {

		@Override
	    protected List<TPlan> doInBackground(Void... params) {

	    	if (tplanIds != null){
	    		
	    		//STEP 1:: get the TPlans of this user
	    		
	    		
	    		List<ParseQuery<ParseObject>> queriesList = new ArrayList<ParseQuery<ParseObject>>();
	    		
	    		for(String tplanId : tplanIds){
	    			ParseQuery<ParseObject> query = ParseQuery.getQuery(TPlanDBHelper.PARSE_DB_TABLENAME_TPLAN);
	    			query.whereEqualTo(UserVSTPlanDBHelper.PARSE_DB_FIELD_TPLANID, tplanId);
	    			queriesList.add(query);
	    		}
	    		
	    		ParseQuery.or(queriesList).findInBackground(new FindCallback<ParseObject>() {
	    		    public void done(List<ParseObject> tplansPO, ParseException e) {
	    		        if (e == null) {
	    		        	if (tplansPO != null && tplansPO.size()> 0){
	    		        		tplans = new ArrayList<TPlan>();
	    		        		for (final ParseObject tplanPO : tplansPO){
	    		        			tplans.add(new TPlan(tplanPO.getString(TPlanDBHelper.PARSE_DB_FIELD_TPLANID),tplanPO.getString(TPlanDBHelper.PARSE_DB_FIELD_NAME),0,0,0));
	    		        		}
	    		        		Log.d(Constants.LOG_TAG, "GetTPlansTask::we successfully retrieved [" + tplansPO.size()+"]");
	    		        		loading.setVisibility(View.GONE);
	    		        		adapter.notifyDataSetChanged();
	    		        	}else if(tplans == null){
	    		        		Log.w(Constants.LOG_TAG, "we couldn't retrieve the tplans: tplans list is NULL");
	    		        	}else{
	    		        		Log.d(Constants.LOG_TAG, "we couldn't retrieve the tplans: tplans list is EMPTY");
	    		        		loading.setVisibility(View.GONE);
	    		        		noTrainingTV.setVisibility(View.VISIBLE);
	    		        	}
	    		        } else {
	    		            Log.d(Constants.LOG_TAG, "Error: " + e.getMessage());
	    		        }
	    		    }
	    		});
	    	}
	    	return null;
	    }
	}
}